module data_memory (
    input clk,
    input rst_n,
    input [31:0] addr,
    input w_en,
    input [2:0] rw_type,
    input [31:0] d_in,
    output [31:0] d_out
);

    reg [31:0] ram[255:0];

    wire [31:0] w_data; // 写入后的数据
    wire [31:0] w_data_B; // 字节写入后的数据
    wire [31:0] w_data_H; // 半字写入后的数据

    wire [31:0] r_data; // 读出的数据
    wire [7:0]  r_data_B;
    wire [15:0] r_data_H;
    wire [31:0] r_data_B_ex; // 扩展（零扩展或符号扩展）
    wire [31:0] r_data_H_ex; // 扩展（零扩展或符号扩展）
    integer i;

    always @(posedge clk) begin
        if (!rst_n) begin
            // 复位时清空ram
            for (i = 0; i < 256; i = i + 1) begin
                ram[i] <= 32'b0;  // 将每个内存单元清零
            end
        end
        else if(w_en) begin
            ram[addr[9:2]] <= w_data; // 由于地址是字节对齐的，所以低2位要屏蔽
        end
    end

    assign w_data_B = (addr[1:0] == 2'b00) ? {r_data[31:8], d_in[7:0]} :
                      (addr[1:0] == 2'b01) ? {r_data[31:16], d_in[7:0], r_data[7:0]} :
                      (addr[1:0] == 2'b10) ? {r_data[31:24], d_in[7:0], r_data[15:0]} : {d_in[7:0], r_data[23:0]};

    assign w_data_H = (addr[1] == 1'b0) ? {r_data[31:16], d_in[15:0]} : {d_in[15:0], r_data[15:0]};

    assign w_data = (rw_type[1:0] == 2'b00) ? w_data_B :
                    (rw_type[1:0] == 2'b01) ? w_data_H : d_in;

    assign r_data = ram[addr[9:2]]; // 读出数据

    assign r_data_B = (addr[1:0] == 2'b00) ? {r_data[7:0]} :
                      (addr[1:0] == 2'b01) ? {r_data[15:8]} :
                      (addr[1:0] == 2'b10) ? {r_data[23:16]} : {r_data[31:24]};
    
    assign r_data_H = (addr[1] == 1'b0) ? {r_data[15:0]} : {r_data[31:16]};

    // 若funct3的高位为0，则使用零扩展，高位为1使用符号扩展
    assign r_data_B_ex = (rw_type[2] == 1'b0) ? {{24{r_data_B[7]}}, r_data_B[7:0]} : {{24{1'b0}}, r_data_B[7:0]};
    assign r_data_H_ex = (rw_type[2] == 1'b0) ? {{16{r_data_H[15]}}, r_data_H[15:0]} : {{16{1'b0}}, r_data_H[15:0]};

    assign d_out = (rw_type[1:0] == 2'b00) ? r_data_B_ex :
                   (rw_type[1:0] == 2'b01) ? r_data_H_ex : r_data;

endmodule